#ifndef SIMULATION_MANAGER_HEADER
#define SIMULATION_MANAGER_HEADER

#include "GL/glfw.h"
#include "3DCamera.h"

class SimulationManager {
public:
	SimulationManager(int w, int h);
	~SimulationManager();

	//Gets the camera.
	DCamera & GetCamera();

	//Main entry point from main.
	int Run();

	//Exit the simulation
	void Quit();

	//Set callbacks
	void SetCallbackEndFrames( void (*func)() ){
		EndFrames = func;
	}

	void SetCallbackInitWindow( bool (*func)() ) {
		InitWindow = func;
	}

	void SetCallbackInitFrames( void (*func)() ) {
		InitFrames = func;
	}

	void SetCallbackUpdate( void (*func)( float ) ) {
		Update = func;
	}

	void SetCallbackDisplay( void (*func) () ) {
		Display = func;
	}

	
	void SetTimeStep( float ts) {mTS = ts;}

	float GetTimeStep() { return mTS; }

	//Pauses simulation
	void Pause() { mIsPaused = !mIsPaused; }

private:

	//Being Main Loop
	void MainLoop();

	//Pools for user input.
	void PollUserInput();

	void InitInputCallbacks();

	bool IsTimeToUpdate(double t);

//*** Callbacks
	//This is for standard keys.
	static void GLFWCALL KeyboardCallback(int uniKey, int state) 
	{
	}

	//If the mouse moves, gives screen x, y.
	static void GLFWCALL MouseMoveCallback(int x, int y) {}

	//If a mouse button is used, it indicates button and state (see GLFW reference).
	static void GLFWCALL MouseButtonCallback(int butt, int state) {}

	bool (*InitWindow)();

	void (*InitFrames)();

	void (*Update)( float );

	void (*Display)();

	void (*EndFrames)();


private:

	//Update time step
	float mTS;
	int mWindowW;
	int mWindowH;
	DCamera mCam;

	//
	bool mIsRunning;

	bool mIsPaused;

	//Default functions
	void _DefaultSMUpdate( float ts );

	bool _DefaultSMInitWindow(int w, int h);
	
	void _DefaultSMInitFrames();

	void _DefaultSMDisplay();

	void _DefaultSMEndFrames();

	
};

#endif